package core.proto.vis.controls;

import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;

import prefuse.Display;
import prefuse.controls.AbstractZoomControl;
import prefuse.controls.Control;
import prefuse.util.ui.UILib;
import prefuse.visual.VisualItem;
import core.util.logging.UserLogWriter;
import core.util.logging.constants.Action;
import core.util.logging.constants.Location;

public class ZoomControl extends AbstractZoomControl
{
	private int yLast;

	private int dy;

	private Point2D down = new Point2D.Float();

	private int button = RIGHT_MOUSE_BUTTON;

	private boolean dragged = false;

	/**
	 * Create a new zoom control.
	 */
	public ZoomControl() {
		// do nothing
	}

	/**
	 * Create a new zoom control.
	 * 
	 * @param mouseButton
	 *            the mouse button that should initiate a zoom. One of
	 *            {@link Control#LEFT_MOUSE_BUTTON},
	 *            {@link Control#MIDDLE_MOUSE_BUTTON}, or
	 *            {@link Control#RIGHT_MOUSE_BUTTON}.
	 */
	public ZoomControl( int mouseButton ) {
		button = mouseButton;
	}

	/**
	 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
	 */
	public void mousePressed( MouseEvent e ) {
		if( UILib.isButtonPressed( e, button ) ) {
			Display display = (Display) e.getComponent();
			if( display.isTranformInProgress() ) {
				yLast = -1;
				return;
			}
			display.setCursor( Cursor
					.getPredefinedCursor( Cursor.N_RESIZE_CURSOR ) );
			display.getAbsoluteCoordinate( e.getPoint(), down );
			yLast = e.getY();
		}
	}

	/**
	 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
	 */
	public void mouseDragged( MouseEvent e ) {
		if( UILib.isButtonPressed( e, button ) ) {
			Display display = (Display) e.getComponent();
			if( display.isTranformInProgress() || yLast == -1 ) {
				yLast = -1;
				return;
			}
			dragged = true;
			int y = e.getY();
			int dy = y - yLast;
			this.dy = dy;
			double zoom = 1 + ((double) dy) / 100;

			int status = zoom( display, down, zoom, true );
			int cursor = Cursor.N_RESIZE_CURSOR;
			if( status == NO_ZOOM )
				cursor = Cursor.WAIT_CURSOR;
			display.setCursor( Cursor.getPredefinedCursor( cursor ) );

			yLast = y;
		}
	}

	/**
	 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
	 */
	public void mouseReleased( MouseEvent e ) {
		if( UILib.isButtonPressed( e, button ) ) {
			e.getComponent().setCursor( Cursor.getDefaultCursor() );
		}
		if (dragged){
			if( dy > 0 ) {
				UserLogWriter.log("Zoom in", Location.Viz, Action.getClicks(e.getClickCount()));
			} else if( dy < 0 ) {
				UserLogWriter.log("Zoom out", Location.Viz, Action.getClicks(e.getClickCount()));
			}
		}
		dragged = false;
	}

	/**
	 * @see prefuse.controls.Control#itemPressed(prefuse.visual.VisualItem,
	 *      java.awt.event.MouseEvent)
	 */
	public void itemPressed( VisualItem item, MouseEvent e ) {
		if( m_zoomOverItem )
			mousePressed( e );
	}

	/**
	 * @see prefuse.controls.Control#itemDragged(prefuse.visual.VisualItem,
	 *      java.awt.event.MouseEvent)
	 */
	public void itemDragged( VisualItem item, MouseEvent e ) {
		if( m_zoomOverItem )
			mouseDragged( e );
	}

	/**
	 * @see prefuse.controls.Control#itemReleased(prefuse.visual.VisualItem,
	 *      java.awt.event.MouseEvent)
	 */
	public void itemReleased( VisualItem item, MouseEvent e ) {
		if( m_zoomOverItem )
			mouseReleased( e );
	}

} // end of class ZoomControl
